//
// Created by meowch on 19-9-8.
//

#ifndef LIBDL_CORE_TENSOROPTIONS_H
#define LIBDL_CORE_TENSOROPTIONS_H

#endif //LIBDL_CORE_TENSOROPTIONS_H

#pragma once

#include <c10/core/TensorOptions.h>
#include <LibDL/utils.h>
#include <LibDL/options/options.h>
#include <LibDL/options/Layout.h>

class TensorOptions {
public:
    using core_type = c10::TensorOptions;
    core_type core;

    ENABLE_CAST;

    TensorOptions() {
        core = c10::TensorOptions();
    };

    TensorOptions(core_type core) : core(core) {
    };

    static TensorOptions empty() {
        return {core_type()};
    }

    explicit TensorOptions(Layout layout) {
        core = c10::TensorOptions();
    }

    explicit TensorOptions(Dtype dType) {
        core = c10::TensorOptions(dType);
    }

    explicit TensorOptions(Device device) {
        core = core_type(device);
    }

    TensorOptions layout(Layout layout) {
        return {this->core.layout(layout)};
    }

    TensorOptions dtype(Dtype dType) {
        return {this->core.dtype(dType)};
    }

    TensorOptions device(Device device) {
        return {this->core.device(device)};
    }

    TensorOptions requires_grad(bool requires_grad) {
        return {this->core.requires_grad(requires_grad)};
    }

#if not defined(Torch_Version_Less_14)
    C10_DEPRECATED_MESSAGE("Tensor.is_variable() is deprecated; everything is a variable now.")
#endif
    TensorOptions is_variable(bool is_variable) {
#ifdef Torch_Version_Less_14
        return {this->core.is_variable(is_variable)};
#else
        //return true for everything is variable now
        return TensorOptions(Dtype(torch::Dtype(true)));
#endif
    }

    TensorOptions pinned_memory(bool pinned_memory) {
        return {this->core.pinned_memory(pinned_memory)};
    }

    std::string toString() {
        std::stringstream ss;
        ss << this->core;
        return ss.str();
    }
};